package com.dimples.controller.system;

import com.dimples.common.annotation.OpsLog;
import com.dimples.common.constant.DimplesConst;
import com.dimples.common.entity.SecurityUser;
import com.dimples.common.enums.OpsLogTypeEnum;
import com.dimples.common.helper.RedisCache;
import com.dimples.common.transport.Result;
import com.dimples.controller.view.BaseWebController;
import com.dimples.system.entity.SysUserOnline;
import com.dimples.system.service.UserOnlineService;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

import javax.validation.constraints.NotBlank;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author zhongyj <1126834403@qq.com><br/>
 * @date 2021/6/26
 */
@Slf4j
@Api(tags = "在线用户管理")
@Validated
@RestController
@RequestMapping(value = BaseWebController.API_SYSTEM_PREFIX)
@RequiredArgsConstructor
public class SysOnlineController {

    private final RedisCache redisCache;
    private final UserOnlineService userOnlineService;

    @ApiOperation(value = "获取在线用户")
    @ApiOperationSupport(order = 1)
    @ApiImplicitParam(name = "username", value = "用户名", paramType = "query")
    @OpsLog(value = "获取在线用户", type = OpsLogTypeEnum.SELECT)
    @GetMapping("online")
    @PreAuthorize("@auth.hasPerm('user:online:view')")
    public Result<SysUserOnline> findOnlineUser(String username) {
        Collection<String> keys = redisCache.keys(DimplesConst.CACHE_KEY_TOKEN_PREFIX + "*");
        List<SysUserOnline> userOnlineList = CollUtil.newArrayList();
        for (String key : keys) {
            JSONObject parseObj = redisCache.getCacheObject(key);
            SecurityUser user = JSONUtil.toBean(parseObj, SecurityUser.class);
            if (StrUtil.isNotBlank(username) && ObjectUtil.isNotEmpty(user)) {
                if (StrUtil.equals(username, user.getUsername())) {
                    userOnlineList.add(this.userOnlineService.selectOnlineByUserName(username, user));
                }
            } else {
                userOnlineList.add(this.userOnlineService.loginUserToUserOnline(user));
            }
        }
        Collections.reverse(userOnlineList);
        userOnlineList.removeAll(Collections.singleton(null));
        return Result.success(userOnlineList);
    }

    @ApiOperation(value = "踢出在线用户")
    @ApiOperationSupport(order = 3)
    @ApiImplicitParam(name = "tokenId", value = "tokenId", paramType = "path", required = true)
    @OpsLog(value = "踢出在线用户", type = OpsLogTypeEnum.DELETE)
    @DeleteMapping("online/{tokenId}")
    @PreAuthorize("@auth.hasPerm('user:online:remove')")
    public Result<SysUserOnline> removeOnlineUser(@NotBlank(message = "不能为空") @PathVariable String tokenId) {
        this.userOnlineService.removeOnlineUser(tokenId);
        return Result.success();
    }

}
